package com.example.iceman.stepcounterapp.widget;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.example.iceman.stepcounterapp.DeviceUtil;
import com.example.iceman.stepcounterapp.R;
import com.example.iceman.stepcounterapp.model.StepRecordEntity;

/**
 * 自定义控件,画柱状图
 * Created by iceman on 16/3/11 17:30
 * 邮箱：xubin865@pingan.com.cn
 */
public class StepRecordView extends View {
    private int mHeight;
    private int mWidth;
    /**
     * 柱形图默认颜色
     */
    private final int RectNormalColor = 0xaa9deced;
    /**
     * 柱形图被选中时的颜色
     */
    private final int RectSelectColor = 0xffffffff;
    /**
     * 上方文字的bottom坐标
     */
    private int topTextLineX;
    /**
     * 下方文字的bottom坐标
     */
    private int bottomTextLineX;
    /**
     * 柱形图区域的bottom坐标
     */
    private int rectBottomLineX;
    /**
     * 上方文字字体大小
     */
    private int topTextFontSize;
    /**
     * 下方文字字体大小
     */
    private int bottomTextFontSize;
    /**
     * 是否需要计算以上各个数据
     */
    private boolean needReset = true;
    /**
     * 绘制过程中的间距,10dp
     */
    private int padding;
    /**
     * 数据源
     */
    private StepRecordEntity[] recordEntities;
    /**
     * 根据数据源计算出来的最大步数
     */
    private int maxStepInt;
    /**
     * 单根柱形的宽度
     */
    private int rectWidth;
    /**
     * 两根柱形之间的间距,实际使用会*2
     */
    private int dividerWidth = 3;
    /**
     * 当前选中的柱形index
     */
    private int currentRectIndex = -1;
    /**
     * 记录按下的坐标点
     */
    private Point downPoint = new Point();
    /**
     * 用来指示当前是哪根柱形的箭头所用的bitmap
     */
    private Bitmap arrowBitmap;
    /**
     * 箭头高
     */
    private int arrowHeight;
    /**
     * 箭头宽
     */
    private int arrowWidth;
    /**
     * 柱形区域总高度
     */
    private int rectAreaHeight;
    /**
     * 柱形图个数,默认显示一天的,24条
     */
    private int rectNum = 24;


    public interface RecordSelectListener {
        void OnRecordSelect(StepRecordEntity entity);
    }

    /**
     * 选中记录的监听
     */
    private RecordSelectListener recordSelectListener;
    /**
     * 用于绘制渐变背景
     */
    private LinearGradient gradient;
    /**
     * 画笔
     */
    private Paint paint;

    public void setRecordSelectListener(RecordSelectListener listener) {
        this.recordSelectListener = listener;
    }


    public StepRecordView(Context context) {
        super(context);
        init();
    }

    public StepRecordView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        arrowBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_step_record_arrow);
        arrowHeight = arrowBitmap.getHeight();
        arrowWidth = arrowBitmap.getWidth();
        paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setAntiAlias(true);
        padding = DeviceUtil.dip2px(10);

    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (needReset) {
            initParams();
        }
        drawBg(canvas);
        drawTexts(canvas);
//        drawHelpLines(canvas);
        if (recordEntities != null && recordEntities.length != 0) {
            drawRects(canvas);
            drawArrow(canvas);
        }
    }

    public void setRectNum(int num) {
        if (num != 0) {
            rectNum = num;
            needReset = true;
            invalidate();
        }
    }

    public void setData(StepRecordEntity[] recordEntities) {
        if (recordEntities == null) {
            return;
        }
        this.recordEntities = recordEntities;
        maxStepInt = 0;
        for (int i = 0; i < recordEntities.length; i++) {
            StepRecordEntity entity = recordEntities[i];
            if (entity.stepInt > maxStepInt) {
                maxStepInt = entity.stepInt;
            }
        }
        invalidate();
    }

    private void drawHelpLines(Canvas canvas) {
        canvas.drawLine(0, topTextLineX, mWidth, topTextLineX, paint);
        canvas.drawLine(0, bottomTextLineX, mWidth, bottomTextLineX, paint);
    }

    private void drawArrow(Canvas canvas) {
        if (currentRectIndex != -1) {
            int left = padding + currentRectIndex * rectWidth + (rectWidth - arrowWidth) / 2;
            canvas.drawBitmap(arrowBitmap, left, rectBottomLineX + padding / 2, paint);
        }
    }

    private void drawBg(Canvas canvas) {
        paint.setColor(0xfff5f5f9);
        paint.setShader(gradient);
        canvas.drawRect(0, 0, mWidth, mHeight, paint);
    }

    private void drawTexts(Canvas canvas) {
        paint.setShader(null);
        paint.setColor(Color.WHITE);


        paint.setTextSize(bottomTextFontSize);
        paint.setTextAlign(Paint.Align.LEFT);
        canvas.drawText("0:00", padding, bottomTextLineX, paint);

        paint.setTextAlign(Paint.Align.CENTER);
        canvas.drawText("12:00", mWidth / 2, bottomTextLineX, paint);

        paint.setTextAlign(Paint.Align.RIGHT);
        canvas.drawText("23:00", mWidth - padding, bottomTextLineX, paint);


        if (currentRectIndex != -1) {
            StepRecordEntity entity = recordEntities[currentRectIndex];

            paint.setTextSize(topTextFontSize);
            paint.setTextAlign(Paint.Align.LEFT);
            canvas.drawText(entity.time, padding, topTextLineX, paint);

            paint.setTextAlign(Paint.Align.CENTER);
            canvas.drawText(String.valueOf(entity.stepInt), mWidth / 2, topTextLineX, paint);

            int offset1 = (int) paint.measureText(String.valueOf(entity.stepInt));
            paint.setTextAlign(Paint.Align.LEFT);
            paint.setTextSize((float) (bottomTextFontSize * 0.8));
            canvas.drawText("步", mWidth / 2 + offset1 / 2, topTextLineX, paint);

            int offset2 = (int) paint.measureText("千卡");
            paint.setTextAlign(Paint.Align.RIGHT);
            canvas.drawText("千卡", mWidth - padding, topTextLineX, paint);

            paint.setTextSize(bottomTextFontSize);
            canvas.drawText(entity.heat, mWidth - padding - offset2, topTextLineX, paint);
        }

    }

    private void getPointRect(int x, int y) {
        int xIndex = (x - padding) / rectWidth;
        if (xIndex >= recordEntities.length) {
            return;
        }
        StepRecordEntity entity = recordEntities[xIndex];
//        int rectTop = rectBottomLineX - entity.stepInt * maxStepInt / rectAreaHeight;
//        if (entity.stepInt > rectTop) {
        if (currentRectIndex != xIndex) {
            currentRectIndex = xIndex;
            invalidate();
            if (recordSelectListener != null) {
                recordSelectListener.OnRecordSelect(entity);
            }
        }
        return;
//        }
    }

    public void setCurrentRectIndex(int index) {
        if (recordEntities == null || index >= recordEntities.length) {
            return;
        }
        currentRectIndex = index;
        invalidate();
    }

    private void drawRects(Canvas canvas) {
        for (int i = 0; i < 24; i++) {
            if (i == currentRectIndex) {
                paint.setColor(RectSelectColor);
            } else {
                paint.setColor(RectNormalColor);
            }
            int top;
            if (recordEntities[i].stepInt == 0) {
                top = rectBottomLineX - 5;
            } else {
                top = rectBottomLineX - recordEntities[i].stepInt * rectAreaHeight / maxStepInt;
            }
            canvas.drawRect(padding + i * rectWidth + dividerWidth, top, padding + i * rectWidth + rectWidth - dividerWidth, rectBottomLineX, paint);
        }

    }

    private void initParams() {
        gradient = new LinearGradient(0, 0, 0, mHeight, getResources().getColor(R.color.title_blue_bg), 0xff55e8ce, Shader.TileMode.CLAMP);

        bottomTextLineX = mHeight - padding;

        topTextFontSize = mHeight / 18;

        bottomTextFontSize = mHeight / 22;

        rectBottomLineX = mHeight - padding * 2 - bottomTextFontSize - arrowHeight;

        topTextLineX = topTextFontSize + padding * 2;

        rectWidth = (mWidth - padding * 2) / rectNum;

        rectAreaHeight = mHeight - padding * 6 - arrowHeight - topTextFontSize - bottomTextFontSize;

        needReset = false;

    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (changed) {
            needReset = true;
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightModel = MeasureSpec.getMode(heightMeasureSpec);
        int widthModel = MeasureSpec.getMode(widthMeasureSpec);
        if (heightModel == MeasureSpec.EXACTLY || widthModel == MeasureSpec.EXACTLY) {
            if (heightModel == MeasureSpec.EXACTLY) {
                int height = MeasureSpec.getSize(heightMeasureSpec);
                mHeight = height;
                mWidth = (int) (height / 0.9);
            } else {
                int width = MeasureSpec.getSize(widthMeasureSpec);
                mWidth = width;
                mHeight = (int) (width * 0.9);
            }
        } else {
            mWidth = 600;
            mHeight = (int) (600 * 0.9);
        }
        setMeasuredDimension(mWidth, mHeight);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downPoint.x = (int) event.getX();
                downPoint.y = (int) event.getY();
                return true;
            case MotionEvent.ACTION_UP:
                int x = (int) event.getX();
                int y = (int) event.getY();
                int distence = (int) Math.sqrt(Math.pow((y - downPoint.y), 2) + Math.pow((x - downPoint.x), 2));
                if (distence < DeviceUtil.dip2px(20)) {
                    getPointRect(x, y);
                }
                break;
        }
        return super.onTouchEvent(event);
    }
}

